#ifndef ENCODER_H__
#define ENCODER_H__
#include "board.h"


/* ---------------------------------------------*/
/* ---------------- Defines ------------------- */
/* ---------------------------------------------*/
//#define ENC_PPR_MULT  4U  // multiple of PPR


/* ---------------------------------------------*/
/* ------------------ Types ------------------- */
/* ---------------------------------------------*/
/**@brief Choose which direction of revolution is treated as positive.*/
typedef enum {
    Enc_DirMode_0 = 0,
    Enc_DirMode_1 = 1,
} Enc_DirMode;


/**@brief Hardware assigned to this encoder.*/
typedef struct {
    TIM_TypeDef* const timx;    
} Enc_HW_TypeDef;


/**@brief Pulic parameters.*/
typedef struct {
    uint8_t DirMode:1;
    uint8_t PulsPerRev;     // pulses per revolution
} Enc_Param_Typedef;


/**@brief The handle of a encoder*/
typedef volatile struct {
    Enc_HW_TypeDef Hw;
    Enc_Param_Typedef Param;
    
    // ===== private params =====
    int32_t s32Loops;           // how many loops has revolved
    uint16_t u16CntZeroPos;     // counter value of zero position within one loop
    bool ParamChanged;
} Enc_TypeDef;


/* ---------------------------------------------*/
/* ---------- Exported Functions -------------- */
/* ---------------------------------------------*/
void Enc_Init(void);
void Enc_Update(Enc_TypeDef* hd);
void Enc_ResetLoops(Enc_TypeDef* hd);
void Enc_ResetLoopsPulses(Enc_TypeDef* hd);
void Enc_GetPosD3(Enc_TypeDef* hd, int32_t* d3Loops);
void Enc_GetPosRaw(Enc_TypeDef* pstEnc, int32_t* s32Loops, int32_t* s32Puls);
int32_t Enc_GetPulsCnt(Enc_TypeDef *pstEnc);

/* ---------------------------------------------*/
/* ---------- Exported Handles -------------- */
/* ---------------------------------------------*/
extern Enc_TypeDef hstEnc_1;
extern Enc_TypeDef hstEnc_2;
extern Enc_TypeDef hstEnc_3;
extern Enc_TypeDef hstEnc_4;



#endif  // ENCODER_H__
